package com.cskaoyan.common.aop;

import com.cskaoyan.bean.entity.Log;
import com.cskaoyan.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * <h1> Log 切片 </h1>
 * Author: GaoJia
 * Date: 2021/10/21 11:23
 */
@Aspect
@Component
public class LogAspect {

    @Resource
    LogMapper logMapper;

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final static Logger LOG = LoggerFactory.getLogger(LogAspect.class);

    /**
     * 定义 后台 Controller 切点
     */
    @Pointcut("execution(public * com.cskaoyan.controller.admin.*Controller.*(..))")
    public void controllerPointcut() {
    }

    @Around("controllerPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        long startTime = System.currentTimeMillis();

        System.out.println("before");
        Object result = joinPoint.proceed();

        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

        Log log = new Log();

        // 1.获取 切点所在的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // log.setResult(result);
        Method method = signature.getMethod();
        // 2.获取 注解属性
        OperateLog annotation = method.getAnnotation(OperateLog.class);
        // 2.1 判空之后插入
        if (annotation != null) {
            Integer type = annotation.opType().length() > 0 ? 1:0;

            log.setType(type);
            log.setAction(annotation.opAction());
            log.setAdmin("admin123");
            log.setIp("111.175.54.189");
            Timestamp timestamp = Timestamp.valueOf(sdf.format(new Date()));

            log.setAddTime(timestamp);
            log.setUpdateTime(timestamp);
            log.setStatus(true);

            logMapper.insertSelective(log);
        }


        LOG.info("------------- 结束 耗时：{} ms -------------", System.currentTimeMillis() - startTime);

        return result;
    }


}
